<?php
/**
 * Created by PhpStorm.
 * User: oujihodo
 * Date: 2022/4/20
 * Time: 10:14
 */

namespace Anchu\Cockpit\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model as ParentModel;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;

class Model extends ParentModel
{
    public $filter;

    public function before()
    {
        $this->filter();
    }

    public function getList()
    {
        $this->before();
        $filter = $this->filter;
        $where = $filter['where'] ?? [];
        $field = $filter['field'] ?? ['*'];
        $orderBy = $filter['orderBy'] ?? [];
        $perPage = $filter['perPage'] ?? 10; // 每页多少条数，为0表示不分页
        $with = $filter['with'] ?? [];
        $page = $filter['page'] ?? 1;   // 当前页数


        $query = self::query()->select($field);
        foreach ($where as $item) {
            if (in_array("in", $item)) {
                $query->whereIn($item[0], $item[2]);
            } else {
                $query->where([$item]);
            }
        }
        foreach ($with as $item) {
            $query->with($item);
        }
        $query = $this->buildOrder($query, $orderBy);
        return $page ? $query->paginate($perPage, $page) : ($perPage ? $query->limit($perPage)->get() : $query->get());
    }

    protected function filter()
    {
        $request = request();
        $perPage = $request->query('per_page', 10);
        $page = $request->query('page', 1);
        $where = [];
        if ($request->query('filter')) {
            $filters = $request->query('filter');
            $filters = is_array($filters) ? $filters : json_decode($filters, 1);
            if (is_array($filters)) {
                foreach ($filters as $name => $value) {
                    if (!is_numeric($name)) {
                        // $filter = ['title' => 'xxx']
                        $where[] = [$name, '=', $value];
                    } elseif (is_array($value) && count($value) == 2) {
                        // $filter = [['title' => 'xxx']]
                        $where[] = [$value[0], '=', $value[1]];
                    } elseif (is_array($value) && count($value) == 3) {
                        // $filter = [['title' ,'like', 'xxx']]
                        if ($value[1] == 'like') {
                            $value[2] = '%' . $value[2] . '%';
                        }
                        // $filter = [['published_at' ,'<=', '2022-09-28']]
                        if ($value[1] == '<=' && strtotime($value[2]) !== false) {
                            $value[2] = Carbon::parse($value[2])->endOfDay()->toDateTimeString();
                        }
                        $where[] = $value;
                    }
                }
            }
        }

        $field = ['*'];
        $orderBy = $request->query('order_by', '{"id": "desc"}');

        $orderBy = json_decode($orderBy, 1);
        $limit = $request->query('limit', 0);
        $this->filter = [
            'where' => $where,
            'perPage' => $perPage,
            'page' => $page,
            'field' => $field,
            'orderBy' => $orderBy,
            'limit' => $limit,
        ];

        return $this->filter;
    }


    public function buildOrder(Builder $query, $orderBy = []): Builder
    {
        if (empty($orderBy)) return $query;

        foreach ($orderBy as $key => $val) {
            if (Str::upper($val) == 'DESC') {
                $query->orderByDesc($key);
            } else {
                $query->orderBy($key);
            }
        }
        return $query;
    }

}
